home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / TinyGL / ami / content / ad709 / tinygl / src / rendertri.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-15  |  7.9 KB  |  383 lines

  1. #include "ztriangle.h"
  2.  
  3. void renderTriangle(ZBuffer *zb, ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2, int color, int _drgbdx,
  4.                     PIXEL    *texture, float    fdzdx, float fndzdx, float ndszdx, float ndtzdx,
  5.            char interp_z_d, char interp_rgb_d, char interp_st_d, char interp_stz_d,
  6.            draw_init_t _draw_init, put_pixel_t _put_pixel, draw_line_t _draw_line) {
  7.  
  8.     ZBufferPoint    *t, *pr1, *pr2, *l1, *l2;
  9.     float            fdx1, fdx2, fdy1, fdy2, fz, d1, d2;
  10.     unsigned short    *pz1;
  11.     PIXEL            *pp1;
  12.     int                part, update_left, update_right;
  13.     int                nb_lines, dx1, dy1, tmp, dx2, dy2;
  14.     int                error, derror;
  15.     int                x1, dxdy_min, dxdy_max;
  16.  
  17.     /* warning: x2 is multiplied by 2^16 */
  18.     int                x2, dx2dy2;
  19.     int                z1, dzdx, dzdy, dzdl_min, dzdl_max;
  20.  
  21.     int                r1, drdx, drdy, drdl_min, drdl_max;
  22.     int                g1, dgdx, dgdy, dgdl_min, dgdl_max;
  23.     int                b1, dbdx, dbdy, dbdl_min, dbdl_max;
  24.  
  25.     int                s1, dsdx, dsdy, dsdl_min, dsdl_max;
  26.     int                t1, dtdx, dtdy, dtdl_min, dtdl_max;
  27.  
  28.     float            sz1, dszdx, dszdy, dszdl_min, dszdl_max;
  29.     float            tz1, dtzdx, dtzdy, dtzdl_min, dtzdl_max;
  30.  
  31.     /* we sort the vertex with increasing y */
  32.     if(p1->y < p0->y) {
  33.         t = p0;
  34.         p0 = p1;
  35.         p1 = t;
  36.     }
  37.  
  38.     if(p2->y < p0->y) {
  39.         t = p2;
  40.         p2 = p1;
  41.         p1 = p0;
  42.         p0 = t;
  43.     }
  44.     else if(p2->y < p1->y) {
  45.         t = p1;
  46.         p1 = p2;
  47.         p2 = t;
  48.     }
  49.  
  50.     /* we compute dXdx and dXdy for all interpolated values */
  51.     fdx1 = p1->x - p0->x;
  52.     fdy1 = p1->y - p0->y;
  53.  
  54.     fdx2 = p2->x - p0->x;
  55.     fdy2 = p2->y - p0->y;
  56.  
  57.     fz = fdx1 * fdy2 - fdx2 * fdy1;
  58.     if(fz == 0) {
  59.         return;
  60.     }
  61.  
  62.     fz = 1.0 / fz;
  63.  
  64.     fdx1 *= fz;
  65.     fdy1 *= fz;
  66.     fdx2 *= fz;
  67.     fdy2 *= fz;
  68.  
  69.     if(interp_z_d) {
  70.         d1 = p1->z - p0->z;
  71.         d2 = p2->z - p0->z;
  72.         dzdx = (int) (fdy2 * d1 - fdy1 * d2);
  73.         dzdy = (int) (fdx1 * d2 - fdx2 * d1);
  74.     }
  75.  
  76.     if(interp_rgb_d) {
  77.         d1 = p1->r - p0->r;
  78.         d2 = p2->r - p0->r;
  79.         drdx = (int) (fdy2 * d1 - fdy1 * d2);
  80.         drdy = (int) (fdx1 * d2 - fdx2 * d1);
  81.  
  82.         d1 = p1->g - p0->g;
  83.         d2 = p2->g - p0->g;
  84.         dgdx = (int) (fdy2 * d1 - fdy1 * d2);
  85.         dgdy = (int) (fdx1 * d2 - fdx2 * d1);
  86.  
  87.         d1 = p1->b - p0->b;
  88.         d2 = p2->b - p0->b;
  89.         dbdx = (int) (fdy2 * d1 - fdy1 * d2);
  90.         dbdy = (int) (fdx1 * d2 - fdx2 * d1);
  91.     }
  92.  
  93.     if(interp_st_d) {
  94.         d1 = p1->s - p0->s;
  95.         d2 = p2->s - p0->s;
  96.         dsdx = (int) (fdy2 * d1 - fdy1 * d2);
  97.         dsdy = (int) (fdx1 * d2 - fdx2 * d1);
  98.  
  99.         d1 = p1->t - p0->t;
  100.         d2 = p2->t - p0->t;
  101.         dtdx = (int) (fdy2 * d1 - fdy1 * d2);
  102.         dtdy = (int) (fdx1 * d2 - fdx2 * d1);
  103.     }
  104.  
  105.     if(interp_stz_d) { {
  106.             float    zz;
  107.             zz = (float) p0->z;
  108.             p0->sz = (float) p0->s * zz;
  109.             p0->tz = (float) p0->t * zz;
  110.             zz = (float) p1->z;
  111.             p1->sz = (float) p1->s * zz;
  112.             p1->tz = (float) p1->t * zz;
  113.             zz = (float) p2->z;
  114.             p2->sz = (float) p2->s * zz;
  115.             p2->tz = (float) p2->t * zz;
  116.  
  117.             d1 = p1->sz - p0->sz;
  118.             d2 = p2->sz - p0->sz;
  119.             dszdx = (fdy2 * d1 - fdy1 * d2);
  120.             dszdy = (fdx1 * d2 - fdx2 * d1);
  121.  
  122.             d1 = p1->tz - p0->tz;
  123.             d2 = p2->tz - p0->tz;
  124.             dtzdx = (fdy2 * d1 - fdy1 * d2);
  125.             dtzdy = (fdx1 * d2 - fdx2 * d1);
  126.         }
  127.     }
  128.  
  129.     /* screen coordinates */
  130.     pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y);
  131.     pz1 = zb->zbuf + p0->y * zb->xsize;
  132.  
  133.     _draw_init(&_drgbdx, drdx, dgdx, dbdx, &color, p2, &fdzdx, &fndzdx, &ndszdx, &ndtzdx, texture,
  134.         &dszdx, &dtzdx, zb, dzdx);
  135.  
  136.     for(part = 0; part < 2; part++) {
  137.         if(part == 0) {
  138.             if(fz > 0) {
  139.                 update_left = 1;
  140.                 update_right = 1;
  141.                 l1 = p0;
  142.                 l2 = p2;
  143.                 pr1 = p0;
  144.                 pr2 = p1;
  145.             }
  146.             else {
  147.                 update_left = 1;
  148.                 update_right = 1;
  149.                 l1 = p0;
  150.                 l2 = p1;
  151.                 pr1 = p0;
  152.                 pr2 = p2;
  153.             }
  154.  
  155.             nb_lines = p1->y - p0->y;
  156.         }
  157.         else {
  158.             /* second part */
  159.             if(fz > 0) {
  160.                 update_left = 0;
  161.                 update_right = 1;
  162.                 pr1 = p1;
  163.                 pr2 = p2;
  164.             }
  165.             else {
  166.                 update_left = 1;
  167.                 update_right = 0;
  168.                 l1 = p1;
  169.                 l2 = p2;
  170.             }
  171.  
  172.             nb_lines = p2->y - p1->y + 1;
  173.         }
  174.  
  175.         /* compute the values for the left edge */
  176.         if(update_left) {
  177.             dy1 = l2->y - l1->y;
  178.             dx1 = l2->x - l1->x;
  179.             if(dy1 > 0) {
  180.                 tmp = (dx1 << 16) / dy1;
  181.             }
  182.             else {
  183.                 tmp = 0;
  184.             }
  185.  
  186.             x1 = l1->x;
  187.             error = 0;
  188.             derror = tmp & 0x0000ffff;
  189.             dxdy_min = tmp >> 16;
  190.             dxdy_max = dxdy_min + 1;
  191.  
  192.             if(interp_z_d) {
  193.                 z1 = l1->z;
  194.                 dzdl_min = (dzdy + dzdx * dxdy_min);
  195.                 dzdl_max = dzdl_min + dzdx;
  196.             }
  197.  
  198.             if(interp_rgb_d) {
  199.                 r1 = l1->r;
  200.                 drdl_min = (drdy + drdx * dxdy_min);
  201.                 drdl_max = drdl_min + drdx;
  202.  
  203.                 g1 = l1->g;
  204.                 dgdl_min = (dgdy + dgdx * dxdy_min);
  205.                 dgdl_max = dgdl_min + dgdx;
  206.  
  207.                 b1 = l1->b;
  208.                 dbdl_min = (dbdy + dbdx * dxdy_min);
  209.                 dbdl_max = dbdl_min + dbdx;
  210.             }
  211.  
  212.             if(interp_st_d) {
  213.                 s1 = l1->s;
  214.                 dsdl_min = (dsdy + dsdx * dxdy_min);
  215.                 dsdl_max = dsdl_min + dsdx;
  216.  
  217.                 t1 = l1->t;
  218.                 dtdl_min = (dtdy + dtdx * dxdy_min);
  219.                 dtdl_max = dtdl_min + dtdx;
  220.             }
  221.  
  222.             if(interp_stz_d) {
  223.                 sz1 = l1->sz;
  224.                 dszdl_min = (dszdy + dszdx * dxdy_min);
  225.                 dszdl_max = dszdl_min + dszdx;
  226.  
  227.                 tz1 = l1->tz;
  228.                 dtzdl_min = (dtzdy + dtzdx * dxdy_min);
  229.                 dtzdl_max = dtzdl_min + dtzdx;
  230.             }
  231.         }
  232.  
  233.         /* compute values for the right edge */
  234.         if(update_right) {
  235.             dx2 = (pr2->x - pr1->x);
  236.             dy2 = (pr2->y - pr1->y);
  237.             if(dy2 > 0) {
  238.                 dx2dy2 = (dx2 << 16) / dy2;
  239.             }
  240.             else {
  241.                 dx2dy2 = 0;
  242.             }
  243.  
  244.             x2 = pr1->x << 16;
  245.         }
  246.  
  247.         /* we draw all the scan line of the part */
  248.         while(nb_lines > 0) {
  249.             nb_lines--;
  250.  
  251.             if (_draw_line == NULL) {
  252.             {    /* generic draw line */
  253.                 register PIXEL            *pp;
  254.                 register int            n;
  255.                 register unsigned short *pz;
  256.                 unsigned int    z, zz;
  257.                 register unsigned int    or1, og1, ob1;
  258.                 unsigned int    s, t;
  259.                 float                    sz, tz;
  260.  
  261.                 // TODO: rgb???
  262.                 int rgb=0, drgbdx=0;
  263.  
  264.                 n = (x2 >> 16) - x1;
  265.                 pp = (PIXEL *) ((char *) pp1 + x1 * PSZB);
  266.  
  267.                 if(interp_z_d) {
  268.                     pz = pz1 + x1;
  269.                     z = z1;
  270.                 }
  271.  
  272.                 if(interp_rgb_d) {
  273.                     or1 = r1;
  274.                     og1 = g1;
  275.                     ob1 = b1;
  276.                 }
  277.  
  278.                 if(interp_st_d) {
  279.                     s = s1;
  280.                     t = t1;
  281.                 }
  282.  
  283.                 if(interp_stz_d) {
  284.                     sz = sz1;
  285.                     tz = tz1;
  286.                 }
  287.  
  288.                 while(n >= 3) {
  289.                     _put_pixel(0, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color, 
  290.                         texture, &s, &t, dsdx, dtdx);
  291.                     _put_pixel(1, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color, 
  292.                         texture, &s, &t, dsdx, dtdx);
  293.                     _put_pixel(2, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
  294.                         texture, &s, &t, dsdx, dtdx);
  295.                     _put_pixel(3, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
  296.                         texture, &s, &t, dsdx, dtdx);
  297.                     
  298.                     if(interp_z_d) {
  299.                         pz += 4;
  300.                     }
  301.  
  302.                     pp = (PIXEL *) ((char *) pp + 4 * PSZB);
  303.                     n -= 4;
  304.                 }
  305.  
  306.                 while(n >= 0) {
  307.                     _put_pixel(0, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
  308.                         texture, &s, &t, dsdx, dtdx);
  309.                     
  310.                     if(interp_z_d) {
  311.                         pz += 1;
  312.                     }
  313.  
  314.                     pp = (PIXEL *) ((char *) pp + PSZB);
  315.                     n -= 1;
  316.                 }
  317.             }
  318.             }
  319.             else {
  320.                 _draw_line(dzdx, _drgbdx, r1, g1, b1, pz1, pp1, x1, x2, z1, sz1, tz1, dszdx, dtzdx, 
  321.                     fdzdx, fndzdx, ndszdx, ndtzdx, texture);
  322.             }
  323.  
  324.             /* left edge */
  325.             error += derror;
  326.             if(error > 0) {
  327.                 error -= 0x10000;
  328.                 x1 += dxdy_max;
  329.  
  330.                 if(interp_z_d) {
  331.                     z1 += dzdl_max;
  332.                 }
  333.  
  334.                 if(interp_rgb_d) {
  335.                     r1 += drdl_max;
  336.                     g1 += dgdl_max;
  337.                     b1 += dbdl_max;
  338.                 }
  339.  
  340.                 if(interp_st_d) {
  341.                     s1 += dsdl_max;
  342.                     t1 += dtdl_max;
  343.                 }
  344.  
  345.                 if(interp_stz_d) {
  346.                     sz1 += dszdl_max;
  347.                     tz1 += dtzdl_max;
  348.                 }
  349.             }
  350.             else {
  351.                 x1 += dxdy_min;
  352.  
  353.                 if(interp_z_d) {
  354.                     z1 += dzdl_min;
  355.                 }
  356.  
  357.                 if(interp_rgb_d) {
  358.                     r1 += drdl_min;
  359.                     g1 += dgdl_min;
  360.                     b1 += dbdl_min;
  361.                 }
  362.  
  363.                 if(interp_st_d) {
  364.                     s1 += dsdl_min;
  365.                     t1 += dtdl_min;
  366.                 }
  367.  
  368.                 if(interp_stz_d) {
  369.                     sz1 += dszdl_min;
  370.                     tz1 += dtzdl_min;
  371.                 }
  372.             }
  373.  
  374.             /* right edge */
  375.             x2 += dx2dy2;
  376.  
  377.             /* screen coordinates */
  378.             pp1 = (PIXEL *) ((char *) pp1 + zb->linesize);
  379.             pz1 += zb->xsize;
  380.         }
  381.     }
  382. }
  383.